# Define here the models for your spider middleware
#
# See documentation in:
# https://docs.scrapy.org/en/latest/topics/spider-middleware.html
import json
import random
import time
import traceback
import os

os.environ['NO_PROXY'] = 'elasticservice.azurewebsites.net'
from scrapy import signals
import requests
from scrapy.http import HtmlResponse

from twisted.internet import defer
from twisted.internet.error import TimeoutError, DNSLookupError, \
    ConnectionRefusedError, ConnectionDone, ConnectError, \
    ConnectionLost, TCPTimedOutError
from twisted.web.client import ResponseFailed
from scrapy.core.downloader.handlers.http11 import TunnelError
from scrapy.utils.project import get_project_settings

setting = get_project_settings()






class Proxy_Redis_DownloaderMiddleware:
    """
    代理处理中间件
    """

    def __init__(self):
        self.proxy_pool = Proxy()

    @classmethod
    def from_crawler(cls, crawler):
        # This method is used by Scrapy to create your spiders.
        s = cls()
        crawler.signals.connect(s.spider_opened, signal=signals.spider_opened)
        return s

    def process_request(self, request, spider):
        """
        每个request 对象经过代理中间件  都会给request对象 从代理池中取出代理
        :param request:
        :param spider:
        :return:
        """
        # Called for each request that goes through the downloader
        # middleware.

        # Must either:
        # - return None: continue processing this request
        # - or return a Response object
        # - or return a Request object
        # - or raise IgnoreRequest: process_exception() methods of
        #   installed downloader middleware will be called
        # proxy_ = random.choice(PROXIES)
        proxy_info = self.proxy_pool.get_proxy()
        print("本次使用了代理:{}".format(proxy_info["proxy"]))
        request.meta["proxy"] = proxy_info["proxy"]
        request.meta["proxy_info"] = proxy_info

        return None

    def process_response(self, request, response, spider):
        # Called with the response returned from the downloader.

        # Must either;
        # - return a Response object
        # - return a Request object
        # - or raise IgnoreRequest
        # proxy = request.meta['proxy']
        # self.proxy_handler.back_to_redis(proxy)

        return response

    def process_exception(self, request, exception, spider):
        # Called when a download handler or a process_request()
        # (from other downloader middleware) raises an exception.

        # Must either:
        # - return None: continue processing this exception
        # - return a Response object: stops process_exception() chain
        # - return a Request object: stops process_exception() chain
        pass

    def spider_opened(self, spider):
        spider.logger.info('Spider opened: %s' % spider.name)

    pass

